JBoss Community Archive (Read Only)

RHQ 4.8

Java Client Sample Class

SampleLdapClientMain.java

package org.rhq.sample.client.java.ldap;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.authz.Permission;
import org.rhq.core.domain.authz.Role;
import org.rhq.core.domain.criteria.ResourceCriteria;
import org.rhq.core.domain.criteria.ResourceGroupCriteria;
import org.rhq.core.domain.criteria.RoleCriteria;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.group.ResourceGroup;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.client.RemoteClient;
import org.rhq.enterprise.server.auth.SubjectManagerRemote;
import org.rhq.enterprise.server.authz.RoleManagerRemote;
import org.rhq.enterprise.server.resource.ResourceManagerRemote;
import org.rhq.enterprise.server.resource.group.ResourceGroupManagerRemote;

/**
 * This sample program utilizes the RHQ Remote API via a Java Client.
 * 
 * The RHQ CLI is the preferred remote client approach for script-based clients.  Programmatic Java clients
 * can utilize the Remote API via the same mechanism used by the CLI, making use of ClientMain object, as
 * done in this sample.  This is the recommended mechanism although a remote Java client could als use the 
 * remote API exposed as WebServices. 
 * 
 * @author Jay Shaughnessy
 */
public class SampleLdapClientMain {
    // A remote session always starts with a login, define default user/password/server/port
    private static String username = "rhqadmin";
    private static String password = "rhqadmin";
    private static String host = "localhost";
    private static int port = 7080;

    /**
     * This is a standalone remote client but calls to the remote API could be embedded into another application.
     */
    public static void main(String[] args) {
        if (args.length > 0) {
            if ((args.length != 2) && (args.length != 4)) {
                System.out
                    .println("\nUsage: SampleLdapClientMain [ [ username password ] | [username password host port] ]");
                System.out.println("\n\nDefault credentials: rhqadmin/rhqadmin");
                System.out.println("\n\nDefault host: determined from wsconsume of WSDL");
                return;
            } else {
                username = args[0];
                password = args[1];

                if (args.length == 4) {
                    host = args[2];
                    port = Integer.valueOf(args[3]);
                }
            }
        }

        LdapClient ldapClient = null;

        try {
            ldapClient = new LdapClient();
            ldapClient.synchLdapJbasManagers();

        } catch (Throwable t) {
            System.out.println("Error: " + t);
            t.printStackTrace();
        } finally {
            if (null != ldapClient) {
                // clean up the session by logging out from the RHQ server
                ldapClient.logout();
            }
        }
    }

    /**
     * The LdapClient interacts with the RHQ Server to help synchronize a (fake) LDAP server with RHQ.  
     */
    public static class LdapClient {
        // group containing all jbas resources
        private static final String JBAS_GROUP = "jbas-resource-group";

        // role for jbas managers
        private static final String JBAS_MANAGER_ROLE = "jbas-manager-role";

        // the users that should be assigned the JBAS_MANAGER_ROLE    
        private static final List<String> JBAS_MANAGERS = new ArrayList<String>();

        // the prmissions that should be assigned the JBAS_MANAGER_ROLE
        private static final Set<Permission> JBAS_MANAGER_PERMISSIONS = new HashSet<Permission>();

        // jbas AS Server resource type (note, this picks up AS4 and AS5 resources as they share the same type name)
        private static final String JBAS_SERVER_NAME = "JBossAS Server";

        /* The Remote API offers different remote "managers" roughly broken down by subsystem/function
         * Below are the managers needed by this client, there are several others that offer
         * interfaces into areas such as operations, alerting, content, etc. See the API. 
         */
        private ResourceGroupManagerRemote resourceGroupManager;
        private ResourceManagerRemote resourceManager;
        private RoleManagerRemote roleManager;
        private SubjectManagerRemote subjectManager;

        /* This represents the RHQ user that is logged in and making the remote calls. This user must
         * already exist.  For the work being done here the user must also have SECURITY_MANAGER permissions.
         */
        private Subject subject;

        /* This is the object through which we access the remote API */
        private RemoteClient remoteClient;

        static {
            // add some fake users since we're not actually hooked into an ldap server
            JBAS_MANAGERS.add("mgr-1");
            JBAS_MANAGERS.add("mgr-2");

            // add some permissions since we're not actually hooked into an ldap server
            JBAS_MANAGER_PERMISSIONS.addAll(Permission.RESOURCE_ALL);
        }

        public LdapClient() throws Exception {
            this.remoteClient = new RemoteClient(null, host, port);
            this.subject = remoteClient.login(username, password);

            this.resourceGroupManager = this.remoteClient.getResourceGroupManagerRemote();
            this.resourceManager = this.remoteClient.getResourceManagerRemote();
            this.roleManager = this.remoteClient.getRoleManagerRemote();
            this.subjectManager = this.remoteClient.getSubjectManagerRemote();
        }

        /*
         * This method simulates a synch between an Ldap server that has defined a group of JBAS managers
         * and wants to associate them with a role allowing jbas management.  Meaning, a role that 
         * has the proper permissions and is associated with the jbas resources.
         */
        private void synchLdapJbasManagers() throws Exception {

            // create the jbas manager role if necessary            
            // use a criteria search with a name filter to look for the role
            RoleCriteria roleCriteria = new RoleCriteria();
            roleCriteria.setFilterName(JBAS_MANAGER_ROLE);
            PageList<Role> jbasManagerRoles = roleManager.findRolesByCriteria(subject, roleCriteria);
            Role jbasManagerRole;
            if (1 == jbasManagerRoles.size()) {
                jbasManagerRole = jbasManagerRoles.get(0);
            } else {
                // if it doesn't exist, create it
                jbasManagerRole = new Role(JBAS_MANAGER_ROLE);
                jbasManagerRole = roleManager.createRole(subject, jbasManagerRole);
            }
            // ensure the proper permissions are granted to the role by using an update
            jbasManagerRole.setPermissions(JBAS_MANAGER_PERMISSIONS);
            roleManager.updateRole(subject, jbasManagerRole);

            // create, populate and associate the jbas group if necessary
            ResourceGroupCriteria resourceGroupCriteria = new ResourceGroupCriteria();
            resourceGroupCriteria.addFilterName(JBAS_GROUP);
            PageList<ResourceGroup> jbasGroups = resourceGroupManager.findResourceGroupsByCriteria(subject,
                resourceGroupCriteria);
            ResourceGroup jbasGroup;
            if (1 == jbasGroups.size()) {
                jbasGroup = jbasGroups.get(0);
            } else {
                jbasGroup = new ResourceGroup(JBAS_GROUP);
                jbasGroup = resourceGroupManager.createResourceGroup(subject, jbasGroup);
                // Ensure the group is recursive to make all the children available.
                // In this case a specific method is available, so a general update call is not needed.
                resourceGroupManager.setRecursive(subject, jbasGroup.getId(), true);
            }

            // Now find all of the JBAS server resources by adding a criteria filter on resource type name
            ResourceCriteria resourceCriteria = new ResourceCriteria();
            resourceCriteria.addFilterResourceTypeName(JBAS_SERVER_NAME);
            PageList<Resource> jbasServers = resourceManager.findResourcesByCriteria(subject, resourceCriteria);
            if (!jbasServers.isEmpty()) {
                int[] jbasServerIds = new int[jbasServers.size()];
                int i = 0;
                for (Resource jbasServer : jbasServers) {
                    jbasServerIds[i++] = jbasServer.getId();
                }

                // ..and add them to the group which will be associated with the manager role
                resourceGroupManager.addResourcesToGroup(subject, jbasGroup.getId(), jbasServerIds);
            }

            // Now, associate the mixed group of Jbas servers to the manager role  
            roleManager.addResourceGroupsToRole(subject, jbasManagerRole.getId(), new int[] { jbasGroup.getId() });

            // synch managers with the role
            // 1. remove obsolete managers
            roleCriteria = new RoleCriteria();
            roleCriteria.setFilterId(jbasManagerRole.getId());
            // add a fetch criteria to the criteria object to get the optionally returned subjects for the role.
            roleCriteria.setFetchSubjects(true);
            jbasManagerRole = roleManager.findRolesByCriteria(subject, roleCriteria).get(0);
            Set<Subject> subjects = jbasManagerRole.getSubjects();
            if ((null != subjects) && !subjects.isEmpty()) {
                for (Subject subject : subjects) {
                    if (!JBAS_MANAGERS.contains(subject.getName())) {
                        roleManager.removeSubjectsFromRole(subject, jbasManagerRole.getId(), new int[] { subject
                            .getId() });
                    }
                }
            }

            // 2. add new managers, create subjects for the managers, if necessary
            Subject jbasManagerSubject;
            for (String jbasManager : JBAS_MANAGERS) {
                jbasManagerSubject = subjectManager.getSubjectByName(jbasManager);
                // add the required fields for a subject, note that we skip credentials since this is 
                // simulating ldap
                if (null == jbasManagerSubject) {
                    jbasManagerSubject = new Subject();
                    jbasManagerSubject.setName(jbasManager);
                    jbasManagerSubject.setEmailAddress("jbas.manager@sample.com");
                    jbasManagerSubject.setFactive(true);
                    jbasManagerSubject.setFsystem(false);
                    jbasManagerSubject = subjectManager.createSubject(subject, jbasManagerSubject);
                }

                // Finally, make sure my current set of jbas managers is associated with the manager role.
                roleManager.addSubjectsToRole(subject, jbasManagerRole.getId(),
                    new int[] { jbasManagerSubject.getId() });
            }
        }

        public void logout() {
            if ((null != subjectManager) && (null != subject)) {
                try {
                    subjectManager.logout(subject);
                } catch (Exception e) {
                    // just suppress the exception, nothing else we can do
                }
            }
        }
    }
}
JBoss.org Content Archive (Read Only), exported from JBoss Community Documentation Editor at 2020-03-12 15:38:07 UTC, last content change 2009-10-07 13:48:20 UTC.